package edu.kpi.pzks2.ui.simulation;

import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;

import net.miginfocom.swing.MigLayout;
import edu.kpi.pzks2.simulator.core.QueueBuilder;
import edu.kpi.pzks2.simulator.core.SimulationBundle;
import edu.kpi.pzks2.simulator.core.SimulationBundle.SimulationBundleBuilder;
import edu.kpi.pzks2.simulator.core.Simulator;
import edu.kpi.pzks2.simulator.impl.PreemptiveStrategy.PreemptiveStrategyFactory;
import edu.kpi.pzks2.simulator.impl.SimpleRouterImpl.SimpleRouterFactory;
import edu.kpi.pzks2.simulator.impl.SimpleStrategy.SimpleStrategyFactory;
import edu.kpi.pzks2.simulator.results.SimulationResult;
import edu.kpi.pzks2.ui.MainFrame;

@SuppressWarnings("serial")
public class SimulationFrame extends JFrame {
    private JDialog prefDialog;
    private final MainFrame mainFrame;
    private final SimulationPanel simPanel;
    
    public SimulationFrame(final MainFrame mainFrame) {
        super("Simulation results");
        
        this.mainFrame = mainFrame;
        
        setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
        
        setSize(new Dimension(500, 500));
        
        simPanel = new SimulationPanel();
        setContentPane(new JScrollPane(simPanel));
    }

    @Override
    public void setVisible(boolean b) {
        super.setVisible(b);
        
        if (b) {
            prefDialog = new SimulationPrefDialog(this);
            prefDialog.setVisible(true);
        }
    }
    
    private class SimulationPrefDialog extends JDialog {
        public SimulationPrefDialog(Frame frame) {
            super(frame, "Simulation preferences");
            
            setSize(270, 550);
            setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
            
            final SimulationPrefsPanel prefsPanel = new SimulationPrefsPanel();
            
            final JButton okButton = new JButton("Simulate");
            okButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {
                    setVisible(false);
                    
                    simulate(
                            prefsPanel.getLinkSpeed(),
                            prefsPanel.getQueueBuilder(),
                            prefsPanel.getProductivity(),
                            prefsPanel.getChannelCount(),
                            prefsPanel.isDuplex(),
                            prefsPanel.isPackageModeOn(),
                            prefsPanel.isSimplePlanning());
                }
            });
            
            final JButton cancelButton = new JButton("Cancel");
            cancelButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    setVisible(false);
                }
            });
            
            final JPanel contentPanel = new JPanel(new MigLayout("", "[][]", "[][]"));
            contentPanel.add(prefsPanel, "cell 0 0 1 0");
            contentPanel.add(okButton, "cell 0 1");
            contentPanel.add(cancelButton, "cell 1 1");
            setContentPane(contentPanel);
        }
    }
    
    private void simulate(
            final int linkSpeed,
            final QueueBuilder queueBuilder,
            final int productivity,
            final int channelCount,
            final boolean isDuplex,
            final boolean isPackageModeOn,
            final boolean isSimplePlanning) {
        final SimulationBundleBuilder simBundleBuilder = new SimulationBundleBuilder();
        
        simBundleBuilder.setSystem(mainFrame.getSystemGraph());
        simBundleBuilder.setTask(mainFrame.getTaskGraph());
        
        // from dialog
        simBundleBuilder.setLinkSpeed(linkSpeed);
        simBundleBuilder.setProductivity(productivity);
        simBundleBuilder.setDuplex(isDuplex);
        simBundleBuilder.setChanelCount(channelCount);
        simBundleBuilder.setQueueBuilder(queueBuilder);
        simBundleBuilder.setPackageMode(isPackageModeOn);
        
        final SimulationBundle simBundle = simBundleBuilder.buildBundle();
        
        final Simulator simulator;
        if (isSimplePlanning) {
            simulator = new Simulator(simBundle, new SimpleStrategyFactory(), new SimpleRouterFactory());
        } else {
            simulator = new Simulator(simBundle, new PreemptiveStrategyFactory(simBundle), new SimpleRouterFactory());
        }
        
//        final Simulator simulator = new Simulator(simBundle, new SimpleStrategyFactory(), new SimpleRouterFactory());
//        final Simulator simulator = new Simulator(simBundle, new NeighbourStrategyFactory(), new SimpleRouterFactory());
//        final Simulator simulator = new Simulator(simBundle, new PreemptiveStrategyFactory(simBundle), new SimpleRouterFactory());
        final SimulationResult res = simulator.start();
        
        System.out.println(res);
        
        simPanel.setData(res.getProcHistories(), res.getChanHistories());
    }
}
